home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / GXEdit Library & Doc / GXEditSelection.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  7.4 KB  |  360 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:                GXEditSelection.c
  3.     
  4.     Contains:
  5.     
  6.     Written by:        Barton R. House
  7.     
  8.     Copyright:        © 1993 by Apple Computer, Inc., All rights reserved.
  9.     
  10. */
  11.  
  12. #include <Script.h>
  13.  
  14. #include "GXEdit.h"
  15. #include "GXEditDoc.h"
  16. #include "GXEditSelection.h"
  17. #include "GXEditParagraph.h"
  18. #include "GXEditStyle.h"
  19. #include "GXEditDebug.h"
  20. #include "GXEditError.h"
  21.  
  22. #include "graphics routines.h"
  23. #include "graphics libraries.h"
  24. #include "font routines.h"
  25. #include "math routines.h"
  26. #include "layout routines.h"
  27.  
  28.  
  29. void SetSelection(DocPtr dp, long start, long end, Boolean setEmptyStyle, Boolean endOfLine, Boolean setMaxLineOffset)
  30. {
  31.     SelPtr            sp;
  32.     ParaPtr            pp;
  33.     NewRunPtr        rp;
  34.     short            runIndex;
  35.     short            runOffset;
  36.     AttrRec            attributes;
  37.     StylePtr            emptyStyle;
  38.     short            lineIndex;
  39.     short            lineOffset;
  40.     
  41.     sp = &dp->selection;
  42.     
  43.     sp->startDocOffset = start;
  44.     sp->endDocOffset = end;
  45.     
  46.     sp->endOfLine = endOfLine;
  47.     
  48.     GetParagraphIndexAndOffset(dp, start, &sp->startParaIndex, &sp->startParaOffset, false);
  49.     GetParagraphIndexAndOffset(dp, end, &sp->endParaIndex, &sp->endParaOffset, endOfLine);
  50.         
  51.     if(start != end) {
  52.     
  53.         attributes.start = true;
  54.         
  55.         GetSelectionAttributes(dp, &attributes);
  56.         
  57.         dp->currentSize = attributes.size;
  58.         
  59.         dp->numCurrentFonts = attributes.numFonts;
  60.         DisposeHandle((Handle) dp->currentFonts);
  61.         dp->currentFonts = attributes.fonts;
  62.         
  63.         dp->numCurrentStyles = attributes.numStyles;
  64.         DisposeHandle((Handle) dp->currentStyles);
  65.         dp->currentStyles = attributes.styles;
  66.                         
  67.     } else {
  68.     
  69.         sp->startParaOffset = sp->endParaOffset;
  70.         sp->startParaIndex = sp->endParaIndex;
  71.     
  72.         pp = *dp->paragraphs + sp->startParaIndex;
  73.                 
  74.         if(sp->startParaOffset == pp->numText && pp->numText) {
  75.         
  76.             /* we don't allow the caret to be placed after the paragraph mark */
  77.             
  78.             sp->startParaOffset--;
  79.             sp->endParaOffset--;
  80.             sp->startDocOffset--;
  81.             sp->endDocOffset--;
  82.             
  83.             sp->endOfLine = false;
  84.             
  85.         }
  86.         
  87.         if(setEmptyStyle) {
  88.         
  89.             GetNewRunIndexAndOffset(dp, pp, sp->startParaOffset, &runIndex, &runOffset);
  90.             
  91.             rp = *pp->runs + runIndex;
  92.             
  93.             /* get the left run if in between runs */
  94.             
  95.             if(runOffset == 0 && runIndex)
  96.                 rp--;
  97.             
  98.             dp->emptyStyle = rp->styleIndex;
  99.             
  100.             /* make sure we are in the correct script/language */
  101.             
  102.             emptyStyle = GetDocStyle(dp, dp->emptyStyle);
  103.             
  104.             if(emptyStyle->script != dp->currentScript || emptyStyle->language != dp->currentLanguage) {
  105.             
  106.                 dp->currentScript = emptyStyle->script;
  107.                 dp->currentLanguage = emptyStyle->language;
  108.                 
  109.                 /* change the keyboard script for the user */
  110.                 
  111.                 KeyScript((short) (dp->currentScript - 1));
  112.                 
  113.             }
  114.         }
  115.             
  116.         if(setMaxLineOffset) {
  117.         
  118.             GetLineIndexAndOffset(dp, *dp->paragraphs + sp->startParaIndex, sp->startParaOffset,  &lineIndex, &lineOffset, sp->endOfLine);
  119.                                  
  120.             dp->maxLineOffset = lineOffset;
  121.         }
  122.         
  123.         dp->currentSize = GetDocStyleTextSize(dp, dp->emptyStyle);
  124.         
  125.         dp->numCurrentFonts = 1;
  126.         SetHandleSize((Handle) dp->currentFonts, sizeof(gxFont));
  127.         (*dp->currentFonts)[0] = GetDocStyleTextFont(dp, dp->emptyStyle);
  128.         
  129.         dp->numCurrentStyles = 1;
  130.         SetHandleSize((Handle) dp->currentStyles, sizeof(short));
  131.         (*dp->currentStyles)[0] = dp->emptyStyle;
  132.         
  133.     }
  134.                 
  135.  
  136. }
  137.  
  138. void GetParagraphIndexAndOffset(DocPtr dp, long docOffset, short * paragraphIndexPtr,
  139.                                                 short * paragraphOffsetPtr, Boolean endOfLine)
  140. {
  141.     ParaPtr            pp;
  142.     short            numParagraphs;
  143.     short            paragraphIndex;
  144.     
  145.     *paragraphIndexPtr = 0;        /* incase of error */
  146.     *paragraphOffsetPtr = 0;
  147.     
  148.     
  149.     pp = *dp->paragraphs;
  150.     
  151.     /* linear search for correct paragraph -- this should be made into a binary search */
  152.     
  153.     numParagraphs = dp->numParagraphs;
  154.     
  155.     for(paragraphIndex = 0; paragraphIndex < numParagraphs; paragraphIndex++, pp++) {
  156.     
  157.         if(docOffset >= pp->docOffset && docOffset < (pp->docOffset + pp->numText)) {
  158.         
  159.             if(endOfLine && docOffset == pp->docOffset && paragraphIndex != 0) {
  160.                 pp--;
  161.                 paragraphIndex--;
  162.             }
  163.         
  164.             *paragraphIndexPtr = paragraphIndex;
  165.             *paragraphOffsetPtr = docOffset - pp->docOffset;
  166.             
  167.             return;
  168.             
  169.         }
  170.         
  171.     }
  172.     
  173.     pp--;
  174.     paragraphIndex--;
  175.     
  176.     *paragraphIndexPtr = paragraphIndex;
  177.     *paragraphOffsetPtr = pp->numText;
  178.         
  179.     
  180. }
  181.  
  182. void GetLineIndexAndOffset(DocPtr dp, ParaPtr pp, short paraOffset, short * lineIndexPtr,  short * lineOffsetPtr, Boolean endOfLine)
  183. {
  184.     LinePtr        lp;
  185.     short        lineIndex;
  186.     
  187.     if(paraOffset < 0 || paraOffset > pp->numText)
  188.         gxEditPostError(dp, gx_edit_internal_fatal_error);
  189.     
  190.     lp = *pp->lines;
  191.     
  192.     /* linear search for now */
  193.     
  194.     for(lineIndex=0; lineIndex < pp->numLines; lineIndex++, lp++) {
  195.     
  196.         if(paraOffset >= lp->paraOffset && paraOffset < (lp->paraOffset + lp->numText)) {
  197.         
  198.             if(endOfLine && lp->paraOffset == paraOffset && lineIndex != 0) {
  199.                 lp--;
  200.                 lineIndex--;
  201.             }
  202.         
  203.             *lineIndexPtr = lineIndex;
  204.             *lineOffsetPtr = paraOffset - lp->paraOffset;
  205.             
  206.             return;
  207.             
  208.         }
  209.     }
  210.     
  211.     lp--;
  212.     lineIndex--;
  213.     
  214.     *lineIndexPtr = lineIndex;
  215.     *lineOffsetPtr = lp->numText;
  216.     
  217. }
  218.  
  219. void GetNewRunIndexAndOffset(DocPtr dp, ParaPtr pp, short paraOffset, short * runIndexPtr,
  220.                                                           short * runOffsetPtr)
  221. {
  222.     NewRunPtr        rp;
  223.     short            runIndex;
  224.     short            numRuns;
  225.     
  226.     if(paraOffset < 0 || paraOffset > pp->numText)
  227.         gxEditPostError(dp, gx_edit_internal_fatal_error);
  228.     
  229.     *runIndexPtr = 0;    /* in case of error */
  230.     *runOffsetPtr = 0;
  231.         
  232.     rp = *pp->runs;
  233.     
  234.     /* linear search for now -- this should be optimized later */
  235.     
  236.     numRuns = pp->numRuns;
  237.     
  238.     for(runIndex=0; runIndex < pp->numRuns; runIndex++, rp++) {
  239.     
  240.         if(paraOffset >= rp->paraOffset && paraOffset < (rp->paraOffset + rp->numText)) {
  241.         
  242.             *runIndexPtr = runIndex;
  243.             *runOffsetPtr = paraOffset - rp->paraOffset;
  244.             
  245.             break;
  246.         }
  247.         
  248.     }
  249.     
  250.     if(runIndex == numRuns && numRuns) {
  251.     
  252.         /* we must want the last spot on the run */
  253.         
  254.         runIndex--;
  255.         rp--;
  256.         
  257.         *runIndexPtr = runIndex;
  258.         *runOffsetPtr = rp->numText;
  259.     
  260.     }
  261.         
  262. }
  263.  
  264. void GetSelectionAttributes(DocPtr dp, AttrPtr ap)
  265. {
  266.     short        paraIndex;
  267.     SelPtr        sp;
  268.     ParaPtr        pp;
  269.     short        startOffset;
  270.     short        endOffset;
  271.     
  272.     sp = &dp->selection;
  273.     
  274.     paraIndex = sp->startParaIndex;
  275.     
  276.     HLock((Handle) dp->paragraphs);
  277.     
  278.     pp = *dp->paragraphs + paraIndex;
  279.     
  280.     ap->start = true;
  281.     
  282.     while(paraIndex <= sp->endParaIndex) {
  283.     
  284.         if(paraIndex == sp->startParaIndex)
  285.             startOffset = sp->startParaOffset;
  286.         else
  287.             startOffset = 0;
  288.             
  289.         if(paraIndex == sp->endParaIndex)
  290.             endOffset = sp->endParaOffset;
  291.         else
  292.             endOffset = pp->numText;
  293.         
  294.         if(startOffset != endOffset)
  295.             GetParagraphAttributes(dp, pp, ap, startOffset, endOffset);
  296.                     
  297.         paraIndex++;
  298.         pp++;
  299.         
  300.     }
  301.     
  302.     HUnlock((Handle) dp->paragraphs);
  303.         
  304. }
  305.  
  306. Boolean SetSelectionStyles(DocPtr dp, short numStyles, short * oldStyles, short * newStyles)
  307. {
  308.     short        paraIndex;
  309.     SelPtr        sp;
  310.     ParaPtr        pp;
  311.     short        startOffset;
  312.     short        endOffset;
  313.     Boolean        modified;
  314.     
  315.     sp = &dp->selection;
  316.     
  317.     if(sp->startDocOffset == sp->endDocOffset) {
  318.     
  319.         if(numStyles != 1)
  320.             gxEditPostError(dp, gx_edit_internal_fatal_error);
  321.         else
  322.             dp->emptyStyle = *newStyles;
  323.  
  324.         return(false);        /* nothing in selection */
  325.     }
  326.     
  327.     paraIndex = sp->startParaIndex;
  328.     
  329.     HLock((Handle) dp->paragraphs);
  330.     
  331.     pp = *dp->paragraphs + paraIndex;
  332.     
  333.     modified = false;
  334.     
  335.     while(paraIndex <= sp->endParaIndex) {
  336.     
  337.         if(paraIndex == sp->startParaIndex)
  338.             startOffset = sp->startParaOffset;
  339.         else
  340.             startOffset = 0;
  341.             
  342.         if(paraIndex == sp->endParaIndex)
  343.             endOffset = sp->endParaOffset;
  344.         else
  345.             endOffset = pp->numText;
  346.         
  347.         if(startOffset != endOffset)
  348.             modified |= SetParagraphStyles(dp, pp, numStyles, oldStyles, newStyles, startOffset, endOffset);
  349.         
  350.         paraIndex++;
  351.         pp++;
  352.         
  353.     }
  354.     
  355.     HUnlock((Handle) dp->paragraphs);
  356.     
  357.     return(modified);
  358.     
  359. }
  360.